package algorithm;

import entity.Professor;
import entity.Room;
import entity.Slot;
import entity.Student;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.w3c.dom.*;
import util.Debug;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import manager.ProfessorManager;
import manager.RoomManager;
import manager.SlotManager;
import manager.StudentManager;

public class Data {

    /**
     * @param args
     */
    private ProfessorManager professorManager;
    List<Professor> _professors;
    List<Student> _students;
    List<Slot> _slots;
    List<Room> _rooms;

    public Data() {
        _students = new LinkedList<Student>();
        _rooms = new LinkedList<Room>();
        _slots = new LinkedList<Slot>();

    }

    public List<Professor> getProfessors() {
        return _professors;
    }

    public List<Student> getStudents() {
        return _students;
    }

    public List<Slot> getSlots() {
        return _slots;
    }

    public List<Room> getRooms() {
        return _rooms;
    }

    public boolean conflictStudents(Student si, Student sj) {

        if (si.juryProfessor(sj.getPresident())) {
            return true;
        }
        if (si.juryProfessor(sj.getSecretary())) {
            return true;
        }
        if (si.juryProfessor(sj.getAdditionalMember())) {
            return true;
        }
        List<Professor> examiner = sj.getExaminerList();
        for (int i = 0; i < examiner.size(); i++) {
            if (si.juryProfessor(examiner.get(i))) {
                return true;
            }
        }
        return false;
    }

    public Professor findProfessor(int id) {
        Professor p = null;
        for (int i = 0; i < _professors.size(); i++) {
            if (_professors.get(i).getId() == id) {
                p = _professors.get(i);
                break;
            }
        }
        return p;
    }

    private Professor addProfessor(int id, String name) {
        Professor p = null;
        for (int i = 0; i < _professors.size(); i++) {
            if (_professors.get(i).getId() == id) {
                p = _professors.get(i);
                break;
            }
        }
        if (p == null) {
            p = new Professor(id, name);
        }
        _professors.add(p);
        return p;

    }

    public void readRoomData(RoomManager roomManager) {
        _rooms = roomManager.getListRoom();
        for (Room room : _rooms) {
            Debug.d(room.getName());
        }
    }

    private void readRoomData(Document doc) {

        NodeList lstRooms = doc.getElementsByTagName("Rooms");
        Node nod_room = lstRooms.item(0);
        Element e_room = (Element) nod_room;
        lstRooms = e_room.getElementsByTagName("room");

        for (int i = 0; i < lstRooms.getLength(); i++) {
            nod_room = lstRooms.item(i);
            e_room = (Element) nod_room;

            NodeList l = e_room.getElementsByTagName("id");
            Element e = (Element) l.item(0);
            l = e.getChildNodes();
            int id = Integer.valueOf(l.item(0).getNodeValue());

            l = e_room.getElementsByTagName("name");
            e = (Element) l.item(0);
            l = e.getChildNodes();
            String name = l.item(0).getNodeValue();

            _rooms.add(new Room(id, name));
        }
        for (int i = 0; i < _rooms.size(); i++) {
            Room r = _rooms.get(i);
            System.out.println(r.getId() + "," + r.getName());
        }
    }

    public void readSlotData(SlotManager slotManager) {
        _slots = slotManager.getListSlots();
        for (Slot s : _slots) {
            Debug.d(s.getDescription());
        }
    }

    private void readSlotData(Document doc) {

        NodeList lstSlots = doc.getElementsByTagName("Slots");
        Node nod_slot = lstSlots.item(0);
        Element e_slot = (Element) nod_slot;
        lstSlots = e_slot.getElementsByTagName("slot");
        for (int i = 0; i < lstSlots.getLength(); i++) {
            nod_slot = lstSlots.item(i);
            e_slot = (Element) nod_slot;

            NodeList l = e_slot.getElementsByTagName("id");
            Element e = (Element) l.item(0);
            l = e.getChildNodes();
            int id = Integer.valueOf(l.item(0).getNodeValue());

            l = e_slot.getElementsByTagName("des");
            e = (Element) l.item(0);
            l = e.getChildNodes();
            String des = l.item(0).getNodeValue();

            _slots.add(new Slot(id, des));
        }
        for (int i = 0; i < _slots.size(); i++) {
            Slot sl = _slots.get(i);
            System.out.println(sl.getID() + "," + sl.getDescription());
        }
    }

    public void readStudentData(StudentManager studentManager) {
        _students = studentManager.getListStudents();
        for (Student s : _students) {
            Professor supervisor = findProfessor(s.getSupervisorId());
            Debug.d(s.getName());
            List<Professor> examiners = new LinkedList<Professor>();
            Professor exm1 = findProfessor(s.getExaminerId1());
            Professor exm2 = findProfessor(s.getExaminerId2());
            exm1.setExaminerId(1);
            exm2.setExaminerId(2);
            examiners.add(exm1);
            examiners.add(exm2);
            Professor president = findProfessor(s.getPresidentId());
            Professor secretary = findProfessor(s.getSecretaryId());
            Professor additionalMember = findProfessor(s.getAdditionalMemberId());
            s.setSupervisor(supervisor);
            s.setExaminerList(examiners);
            s.setPresident(president);
            s.setSecretary(secretary);
            s.setAdditionalMember(additionalMember);
            s.setExaminer1(exm1);
            s.setExaminer2(exm2);
        }
    }

    private void readStudentData(Document doc) {

        NodeList lstStudents = doc.getElementsByTagName("Students");
        Node c = lstStudents.item(0);
        Element e = (Element) c;

        lstStudents = e.getElementsByTagName("Student");
        //System.out.println("Number of courses = " + lstCourses.getLength());
        for (int i = 0; i < lstStudents.getLength(); i++) {
            //System.out.println("i = " + i);
            c = lstStudents.item(i);
            //if(c == null) System.out.println("c = NULL");
            if (c.getNodeType() == Node.ELEMENT_NODE) {
                e = (Element) c;
                NodeList l = e.getElementsByTagName("name");
                Node nod = l.item(0);
                Element e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                //System.out.println("Get course name = " + l.item(0).getNodeValue());
                String student_name = l.item(0).getNodeValue();

                l = e.getElementsByTagName("id");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                //System.out.println("Get course id = " + l.item(0).getNodeValue());
                int student_id = Integer.valueOf(l.item(0).getNodeValue());

                l = e.getElementsByTagName("title");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                String thesis_title = l.item(0).getNodeValue();

                //System.out.println(student_name + " " + student_id + thesis_title);
                l = e.getElementsByTagName("supervisor");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                int supervisor_id = Integer.valueOf(l.item(0).getNodeValue());
                Professor supervisor = findProfessor(supervisor_id);

                l = e.getElementsByTagName("examiner");
                List<Professor> examiners = new LinkedList<Professor>();
                for (int j = 0; j < l.getLength(); j++) {
                    Node cj = l.item(j);
                    Element e_cj = (Element) cj;
                    NodeList lj = e_cj.getChildNodes();
                    int idj = Integer.valueOf(lj.item(0).getNodeValue());
                    Professor pj = findProfessor(idj);
                    examiners.add(pj);
                }

                l = e.getElementsByTagName("president");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                Professor president = findProfessor(Integer.valueOf(l.item(0).getNodeValue()));

                l = e.getElementsByTagName("secretary");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                Professor secretary = findProfessor(Integer.valueOf(l.item(0).getNodeValue()));

                l = e.getElementsByTagName("additionalmember");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                Professor additionalMember = findProfessor(Integer.valueOf(l.item(0).getNodeValue()));

                Student s = new Student(student_id, student_name, thesis_title, supervisor, examiners, president, secretary, additionalMember);
                _students.add(s);
            }

        }

        for (int i = 0; i < _students.size(); i++) {
            Student s = _students.get(i);
            s.println();
        }

    }

    public void readProfessorData(ProfessorManager professorManager) {
        Debug.d("read professor data");
        this._professors = professorManager.getListProfessors();
        for (int i = 0; i < _professors.size(); i++) {
            Professor p = _professors.get(i);
            p.println();
        }
    }

    private void readProfessorData(Document doc) {

        NodeList lstInstructors = doc.getElementsByTagName("Professors");
        Node nod_lstInstructors = lstInstructors.item(0);
        Element e_lstInstructors = (Element) nod_lstInstructors;

        lstInstructors = e_lstInstructors.getElementsByTagName("Professor");
        //System.out.println("lstInstructors.length = " + lstInstructors.getLength());
        for (int i = 0; i < lstInstructors.getLength(); i++) {
            Node c = lstInstructors.item(i);
            //System.out.println("Process node " + i + " c = " + c.getNodeName());
            if (c.getNodeType() == Node.ELEMENT_NODE) {
                Element e = (Element) c;
                NodeList l = e.getElementsByTagName("name");
                Node nod = l.item(0);
                Element e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                //System.out.println("Get instructor name = " + l.item(0).getNodeValue());
                String professor_name = l.item(0).getNodeValue();

                l = e.getElementsByTagName("id");
                nod = l.item(0);
                e_nod = (Element) nod;
                l = e_nod.getChildNodes();
                //System.out.println("Get instructor id = " + l.item(0).getNodeValue());
                int professor_id = Integer.valueOf(l.item(0).getNodeValue());

                //System.out.println("start addInstructor " + instructor_id);
                Professor p = addProfessor(professor_id, professor_name);

                //System.out.println("start addInstructor " + instructor_id + " --> OK, _instructors.size = " + _instructors.size());
            }
        }
        //System.out.println("read instructors --> OK, start  printing");
        for (int i = 0; i < _professors.size(); i++) {
            Professor p = _professors.get(i);
            p.println();
            //System.out.println("");
        }

    }

    public void readData(String filename) {
        try {
            //System.out.println("try");

            DocumentBuilderFactory docBF = DocumentBuilderFactory.newInstance();
            DocumentBuilder docB = docBF.newDocumentBuilder();
            Document doc = docB.parse(new File(filename));
            doc.getDocumentElement().normalize();
            //System.out.println("Root element of the document is " + doc.getDocumentElement().getNodeName());
            readRoomData(doc);
            readProfessorData(doc);
            readSlotData(doc);
            readStudentData(doc);

            //assert(false);




        } catch (SAXParseException err) {
            System.out.println("Parsing error at line " + err.getLineNumber() + ", uri = " + err.getSystemId());
            System.out.println("error message is: " + err.getMessage());
        } catch (SAXException e) {
            Exception x = e.getException();
            ((x == null) ? e : x).printStackTrace();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public void setProfessorManager(ProfessorManager professorManager) {
        this.professorManager = professorManager;
    }

    public ProfessorManager getProfessorManager() {
        return professorManager;
    }
}
